package com.work.cloudseata.service;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.generator.SnowflakeGenerator;
import cn.hutool.json.JSONUtil;
import com.work.cloudseata.client.PermissionService;
import com.work.cloudseata.entity.User;
import com.work.cloudseata.repository.UserRepository;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class UserService {

    @Autowired
    private UserRepository repository;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private StreamBridge streamBridge;

    private final SnowflakeGenerator generator = new SnowflakeGenerator();

    @GlobalTransactional
    public void register(User user, String ip) {
        Optional<User> optional = repository.findByUsername(user.getUsername());
        if (optional.isPresent()) {
            throw new RuntimeException("用户名已被注册");
        }
        user.setUserId(generator.next());
        user.setGmtCreate(new Date());
        repository.save(user);
        permissionService.bindDefaultRole(user.getUserId());
        streamBridge.send("register-out-0", MessageBuilder.withPayload(JSONUtil.toJsonStr(user)).setHeader("userId", user.getUserId()).setHeader("ip", ip).build());
    }

    public String login(String username, String password) {
        User user = repository.findByUsername(username).orElseThrow(() -> new RuntimeException("用户不存在"));
        if (!user.getPassword().equals(password)) {
            throw new RuntimeException("密码错误");
        }
        StpUtil.login(user.getUserId());
        return StpUtil.getTokenValue();
    }

    public List<User> list() {
        if (StpUtil.hasRole("super_admin")) {
            return repository.findAll();
        } else if (StpUtil.hasRole("admin")) {
            List<Long> userIds = permissionService.roleUserList();
            return repository.findAllById(userIds);
        }
        Long userId = Long.valueOf(StpUtil.getLoginId().toString());
        return repository.findAllById(List.of(userId));
    }

    public User getById(Long id) {
        if (StpUtil.hasRole("super_admin")) {
            return repository.findById(id).orElse(null);
        } else if (StpUtil.hasRole("admin")) {
            List<Long> userIds = permissionService.roleUserList();
            return userIds.contains(id) ? repository.findById(id).orElse(null) : null;
        }
        Long userId = Long.valueOf(StpUtil.getLoginId().toString());
        return Objects.equals(userId, id) ? repository.findById(id).orElse(null) : null;
    }

    public void updateById(Long id, User input) {
        User entity = repository.findById(id).orElseThrow(() -> new RuntimeException("用户不存在"));
        if (StpUtil.hasRole("super_admin")) {
            entity.setPhone(input.getPhone());
            entity.setEmail(input.getEmail());

        } else if (StpUtil.hasRole("admin")) {
            List<Long> userIds = permissionService.roleUserList();
            if (userIds.contains(id)) {
                entity.setPhone(input.getPhone());
                entity.setEmail(input.getEmail());
            }
        } else {
            Long userId = Long.valueOf(StpUtil.getLoginId().toString());
            if (Objects.equals(userId, id)) {
                entity.setPhone(input.getPhone());
                entity.setEmail(input.getEmail());
            }
        }
        repository.save(entity);
    }

    public void resetPassword(User input) {
        User entity = repository.findById(input.getUserId()).orElseThrow(() -> new RuntimeException("用户不存在"));
        if (StpUtil.hasRole("super_admin")) {
            entity.setPassword(input.getPassword());

        } else if (StpUtil.hasRole("admin")) {
            List<Long> userIds = permissionService.roleUserList();
            if (userIds.contains(entity.getUserId())) {
                entity.setPassword(input.getPassword());
            }
        } else {
            Long userId = Long.valueOf(StpUtil.getLoginId().toString());
            if (Objects.equals(userId, entity.getUserId())) {
                entity.setPassword(input.getPassword());
            }
        }
        repository.save(entity);
    }

    public void upgrade(Long id) {
        repository.findById(id).orElseThrow(() -> new RuntimeException("用户不存在"));
        if (!StpUtil.hasRole("super_admin")) {
            throw new RuntimeException("只能超级管理员操作");
        }
        permissionService.upgradeToAdmin(id);
    }

    public void downgrade(Long id) {
        repository.findById(id).orElseThrow(() -> new RuntimeException("用户不存在"));
        if (!StpUtil.hasRole("super_admin")) {
            throw new RuntimeException("只能超级管理员操作");
        }
        permissionService.downgradeToUser(id);
    }
}
